import { t } from 'i18next'
import createVanilla from 'zustand/vanilla'
import create from 'zustand'
import { ISysMsg, transSystemInfo } from '@/api/manager/helper/translator'
import { ApplyMsgItem, CometdMessage } from '@/api/manager/helper/interface'
import { store as delayMeetingStore } from '@/pages/manager/blocks/meetingInfoSet/store'
import { fetchApplyOperate } from '@/api/manager/helper/index'
import { Alert } from '@/components/Alert'
import { Modal, ModalInstance } from '@kedacom/react-next'
import { fetchInteractive, fetchRejectDiscussApply, fetchSetChairman } from '@/api/manager/actions'
import { useMccStore } from '../../store'
import { Mt, MtEntity } from '@/api/manager/mt'
import { subscribeWithSelector } from 'zustand/middleware'
import { ITab, InnerApplyMsgItem, TabItem } from './interface'

interface MsgType {
	type: string
	id: string
	msg: string
	sender: string
	index: number
}
interface MssStore {
	// 申请互动弹窗权限队列
	discussQueue: Array<ModalInstance>
	//页面底部显示的消息
	sysMessage: MsgType
	//系统推送消息队列
	msgCache: Array<
		CometdMessage & {
			index: number
		}
	>
	// 非互动终端申请成为发言方，会同时发送mcc_sysmsg_mtapplydiscuss和mcc_sysmsg_mtapplyspeaker两个cometd消息，加锁三秒内自动同意申请发言人
	lock: Array<{
		key: string
		timer: null | NodeJS.Timeout
	}>
	// 管理方申请弹窗
	chairmanDialog: Array<{
		name: string
		modal: ModalInstance
	}>
	//是否显示帮助
	showHelper: boolean
	// 标签
	tab: ITab
	// tab数据
	tabData: TabItem[]
	//系统消息列表
	systemInfoList: ISysMsg[]
	//是否显示审批提示
	showApplyTip: boolean
	//审批申请列表
	applyList: ApplyMsgItem[]
	//实际展示的审批申请列表
	innerApplyList: InnerApplyMsgItem[]
}
type MsgStore = MssStore & {
	update: (d: Partial<MssStore>) => void
	reset: () => void
	handleShow: (d: boolean) => void
	getMsgByIndex: (index: number) => boolean
	showMsg: (
		msg?: CometdMessage & {
			index: number
		},
		isNew?: boolean
	) => void
	show: (
		msg: CometdMessage & {
			index: number
		},
		isNew?: boolean
	) => void
	msgHandle: (data: CometdMessage) => void
	msgPopup: (data: CometdMessage) => void
	clearLock: (data: string) => void
	updateApplyMsgList: (data: ApplyMsgItem[]) => void
}
const initialState: MssStore = {
	chairmanDialog: [],
	discussQueue: [],
	msgCache: [],
	sysMessage: {
		type: '',
		id: '',
		msg: '',
		sender: '',
		index: -1,
	},
	lock: [],
	showHelper: false,
	tab: 'apply',
	tabData: [
		{ name: 'apply', label: t('审批终端申请') },
		{ name: 'checking', label: t('检测终端') },
		{ name: 'systemInfo', label: t('查看系统消息') },
	],
	systemInfoList: [],

	showApplyTip: false,
	applyList: [],
	innerApplyList: [],
}
export const store = createVanilla<MsgStore>()(
	subscribeWithSelector((set, get) => ({
		...initialState,
		update: (d) => set({ ...d }),
		reset: () => set(initialState),
		handleShow: (d) => {
			const { sysMessage, msgCache, getMsgByIndex, showMsg } = get()
			if (sysMessage.index === 0) {
				showMsg()
				return
			}
			if (d) {
				// perv
				for (let i = 0; i < msgCache.length; i++) {
					let result = getMsgByIndex(sysMessage.index - 1)
					if (result) {
						break
					}
				}
			} else {
				//next
				for (let i = 0; i < msgCache.length; i++) {
					let result = getMsgByIndex(sysMessage.index + 1)
					if (result) {
						break
					}
				}
			}
		},
		showMsg: (message, isNew) => {
			const { msgCache, show } = get()
			if (message) {
				msgCache.push(message)
			} else {
				if (msgCache.length === 0) {
					return
				}
				message = msgCache[msgCache.length - 1]
			}
			if (msgCache.length > 1) {
				message.index = msgCache[msgCache.length - 2].index + 1
			} else {
				message.index = msgCache.length
			}
			show(message, isNew)
		},
		getMsgByIndex: (index) => {
			const { msgCache, show } = get()
			let message = null
			if (index <= 0) {
				index = 1
			}
			for (let i = 0; i < msgCache.length; i++) {
				if (msgCache[i].index === index) {
					message = msgCache[i]
					break
				}
			}
			if (!message) return false
			show(message)
			return true
		},
		show: (message) => {
			let data = transSystemInfo(message)
			const { name, msg } = data
			set({
				sysMessage: {
					id: message.id || '',
					msg: msg,
					sender: name,
					index: message.index || 0,
					type: message.type,
				},
			})
		},
		msgHandle: (data) => {
			const { showMsg, msgPopup, tab, showHelper } = get()
			if (data.time_left && data.type === 'mcc_sysmsg_timeleft' && Number(data.time_left) <= 15) {
				delayMeetingStore.getState().initDelayMeeting({ from: 1, time: Number(data.time_left) })
			}
			showMsg({ ...data, index: 0 })
			//当前如果打开了会议助手的系统消息，那就根据推送实时添加入会议助手系统消息列表
			if (showHelper && tab === 'systemInfo') {
				let cur = transSystemInfo(data)
				set((v) => ({ systemInfoList: [cur, ...v.systemInfoList] }))
			}
			if (
				data.type === 'mcc_sysmsg_mtapplyspeaker' ||
				data.type === 'mcc_sysmsg_mtapplyadmin' ||
				data.type === 'mcc_sysmsg_mtapplydiscuss' ||
				data.type === 'mcc_sysmsg_mt_apply_cancel_mute' ||
				data.type === 'mcc_sysmsg_mtapplymix' ||
				data.type === 'err_mcu_rollcall_calleeleft'
			) {
				msgPopup(data)
			}
			if (data._isMonitorPopup) {
				msgPopup(data)
			}
		},
		msgPopup: (data) => {
			const sender = data.operation_user ? data.operation_user.name : ''
			const mt_id = data.operation_user ? data.operation_user.mt_id : ''
			const moid = data.operation_user ? data.operation_user.account + data.operation_user.account_type : null
			const mt = data.operation_user ? new Mt(data.operation_user as MtEntity) : ''
			if (data) {
				if (data.type === 'err_mcu_confoverflow') {
					Alert(t('当前没有空闲的会议资源，召开会议失败(20101)'))
				} else if (data.type === 'err_mcu_no_idle_mix') {
					Alert(t('当前没有空闲的会议资源，开启混音失败(20903)'))
				} else if (data.type === 'err_mcu_spymtisunusualormodeerror') {
					Alert(t('终端或媒体异常，操作失败(21756)'))
				} else if (data.type === 'err_mcu_oprinvalid_notsupportmulticascade') {
					Alert(t('该级联会议不支持此操作(21742)'))
				} else if (data.type === 'err_mcu_no_idle_vmp') {
					Alert(t('当前没有空闲的会议资源，开启画面合成失败(20901)'))
				} else if (data.type === 'err_mcu_callvrsrecfail') {
					Alert(t('录播服务器连接失败，请联系管理员(20851)'))
				} else if (data.type === 'err_mcu_resource_out') {
					Alert(t('开启失败，录播服务器资源不足(24102)'))
				} else if (data.type === 'err_mcu_repeat_filename') {
					Alert(t('录像文件名已存在，请重新输入(24105)'))
				} else if (data.type === 'err_mcu_file_out_ability') {
					Alert(t('无法播放，放像文件与会议能力不匹配(24107)'))
				} else if (data.type === 'err_mcu_confnotsupportmultispy') {
					Alert(t('本级会议回传功能没打开(21738)'))
				} else if (data.type === 'err_mcu_confsndbandwidthisfull') {
					Alert(t('上级会议与下级会议之间回传带宽不足，回传失败(21740)'))
				} else if (data.type === 'err_mcu_casdbasisnotenough') {
					Alert(t('本级会议能力不足，操作失败(21741)'))
				} else if (data.type === 'err_mcu_casadeportfnotenough') {
					Alert(t('本级会议能力不足，操作失败(21750)'))
				} else if (data.type === 'err_mcu_confstartvacpollmode') {
					Alert(t('会议轮询和语音激励不能同时开启，关闭语音激励，去设置...(20355)'))
				} else if (data.type === 'mcc_sysmsg_mt_apply_cancel_mute') {
				} else if (data.type === 'err_mcu_vrs_notsupponlylive') {
					Alert(t('当前版本开启直播功能需要勾选录像功能(20855)'))
				} else if (data.type === 'err_mcu_vrs_notenoughlivesource') {
					Alert(t('直播资源不足(24205)'))
				} else if (data.type === 'err_mcu_vrs_notenoughspace') {
					Alert(t('当前录播服务器存储空间已满，请联系管理员(24122)'))
				} else if (data.type === 'err_mcu_vrs_disconnected') {
					Alert(t('当前录播服务器和外置存储已断开，请联系管理员(24108)'))
				} else if (data.type === 'err_mcu_vrs_fileexception') {
					Alert(t('录像文件内容异常，开启直播失败，请联系管理员(24304)'))
				} else if (data.type === 'err_mcu_confplaying') {
					Alert(t('会议放像时，不能同时操作其他申请发言人行为(20804)'))
				} else if (data.type === 'err_mcu_vrs_outdate') {
					Alert(t('开启失败，您购买的直播已过期(24109)'))
				} else if (data.type === 'err_mcu_vrs_limit') {
					Alert(t('当前直播会议已满，请联系管理员(24110)'))
				} else if (data.type === 'err_mcu_vrs_smmatchsafecapfail') {
					Alert(t('开启失败，当前会议系统与录播系统安全类型不匹配(20858)'))
				} else if (data.type === 'err_vmp_no_vip_vmpchnnl') {
					Alert(t('解码能力不足(20834)'))
				} else if (data.type === 'err_mcu_pureconfforbidvmp') {
					Alert(t('当前为纯转发会议，开启画面合成失败(20847)'))
				} else if (data.type === 'err_mcu_pureconfforbidmix') {
					Alert(t('当前为纯转发会议，开启混音或语音激励失败(20848)'))
				} else if (data.type === 'err_mcu_polling_nomtorvidsrc') {
					Alert(t('请添加可轮询终端，再开启轮询(20524)'))
				} else if (data.type === 'err_mcu_vrs_chgspymt') {
					Alert(t('上传通道已被替换， 原终端录像停止(20854)'))
				} else if (data.type === 'err_mcu_exceeedvmpsinglenum') {
					Alert(t('设置的单通道轮询通道数已超过9个，部分通道可能无法正常显示(20846)'))
				} else if (data.type === 'err_mcu_selvidbasisnotenough') {
					Alert(t('视频适配资源不足，选看失败(20509)'))
				} else if (data.type === 'err_mcu_vrs_addvrsmtfailed') {
					Alert(t('开启失败，当前会议资源使用已达上限(20860)'))
				} else if (data.type === 'err_mcu_mcuisdumb') {
					Alert(t('当前发言人所在会议被哑音，影响发言人的声音(21757)'))
				} else if (data.type === 'err_mcu_vrs_vrsconnectfailed') {
					Alert(t('开启失败，多媒体录播服务器连接异常(20861)'))
				} else if (data.type === 'err_mcu_rollcall_calleeleft') {
					Alert(t('被点名人处于离线状态(20543)'))
				} else if (data.error_code && data.error_code >= 29301 && data.error_code <= 29461) {
					Alert(
						t('端口资源不足，可能导致终端无法正常进行视频交流，您可申请更多资源({{errorcode}})', {
							errorcode: data.error_code,
						})
					)
				} else if (data.type === 'err_mcu_mediaresnotenough') {
					Alert(t('端口资源不足，可能导致终端无法正常进行视频交流，您可申请更多资源(21751)'))
				} else if (data.type === 'err_mcu_spymtstate_waitfree') {
					Alert(t('上级会议与下级会议之间回传带宽不足，回传失败(21744)'))
				} else if (data.type === 'mcc_sysmsg_mtapplydiscuss') {
					const meetingMoid = useMccStore.getState().mccInfo.meetingMoid
					const { discussQueue, lock, clearLock } = get()
					let discussDlg = Modal.confirm({
						title: t('提示'),
						content: t('{{name}}申请互动发言', { name: sender }),
						okText: t('同意'),
						cancelText: t('拒绝'),
						onOk: () => {
							mt && mt_id && fetchInteractive(meetingMoid, mt)
							discussQueue.map((i) => i.hide())
							set({ discussQueue: [] })
							//非互动终端申请成为发言方，会同时发送mcc_sysmsg_mtapplydiscuss和mcc_sysmsg_mtapplyspeaker两个cometd消息，加锁三秒内自动同意申请发言人
							if (moid) {
								const obj = lock.filter((item) => item.key === 'setSpeaker' + moid)
								if (obj.length > 0) {
									lock.forEach((item) => {
										if (item.key === 'setSpeaker' + moid) {
											item.timer && clearTimeout(item.timer)
											item.timer = setTimeout(() => {
												clearLock(item.key)
											}, 3000)
										}
									})
								} else {
									lock.push({
										key: 'setSpeaker' + moid,
										timer: setTimeout(() => {
											clearLock('setSpeaker' + moid)
										}, 3000),
									})
								}
								set({
									lock: [...lock],
								})
							}
						},
						onCancel: () => {
							mt && fetchRejectDiscussApply(meetingMoid, mt)
							discussDlg.hide()
						},
					})
					discussQueue.push(discussDlg)
					set({ discussQueue: discussQueue })
				} else if (data.type === 'mcc_sysmsg_mtapplyspeaker') {
					const { lock } = get()
					const meetingMoid = useMccStore.getState().mccInfo.meetingMoid
					const flag = lock.filter((item) => item.key === 'setSpeaker' + moid && item.timer)
					if (moid && flag.length > 0) {
						if (data.id) {
							fetchApplyOperate(
								meetingMoid,
								data.operation_user?.mt_id || data.operation_user?.account || '',
								data.id,
								{ state: 2 }
							) //同意成为发言方
						}
					}
				} else if (data.type === 'mcc_sysmsg_mtapplyadmin') {
					const { chairmanDialog } = get()
					const index = chairmanDialog.findIndex((item) => item.name === `chairmanDlg_${sender}`)
					if (index > -1) {
						return
					}
					let m = Modal.confirm({
						title: t('提示'),
						content: t('{{name}}申请成为管理方', { name: sender }),
						okText: t('同意'),
						cancelText: t('拒绝'),
						onOk: () => {
							const meetingMoid = useMccStore.getState().mccInfo.meetingMoid
							mt && fetchSetChairman(meetingMoid, mt)
							m.hide()
							set({
								chairmanDialog: [
									...chairmanDialog.filter((item) => item.name !== `chairmanDlg_${sender}`),
								],
							})
						},
						onCancel: () => {
							m.hide()
							set({
								chairmanDialog: [
									...chairmanDialog.filter((item) => item.name !== `chairmanDlg_${sender}`),
								],
							})
						},
					})
					set({
						chairmanDialog: [...chairmanDialog, { name: `chairmanDlg_${sender}`, modal: m }],
					})
				}
			}
		},
		clearLock: (key) => {
			const { lock } = get()
			const newLock = lock.filter((item) => {
				if (item.key === key) {
					item.timer && clearTimeout(item.timer)
					return false
				} else {
					return item
				}
			})
			set({ lock: [...newLock] })
		},
		updateApplyMsgList: (data) => {
			const { showHelper, innerApplyList } = get()
			set({ applyList: data })
			if (!showHelper) {
				set({ showApplyTip: data.length > 0 }) //展示终端审批弹窗
			} else {
				//当前如果打开了会议助手的审批申请，那就根据推送实时修改会议助手审批申请列表
				let ids = innerApplyList.map((i) => i.id) //当前展示的终端申请id
				let curIds = data.map((i) => i.id) //当前申请列表id
				let newList = [...innerApplyList].filter((i) => curIds.includes(i.id) || i.done) //删除撤销的未审批申请
				//推送的某一条消息不存在与当前列表中，插入列表头部
				data.reverse().forEach((item) => {
					if (!ids.includes(item.id)) {
						newList.unshift({ ...item, done: false })
					}
				})
				set({ innerApplyList: newList })
			}
		},
	}))
)
export const useMsgStore = create(store)
